Skip to content

Fix Direct Boot accessibility startup#2153

Open
smh786 wants to merge 3 commits into
keymapperorg:developfrom
smh786:codex/direct-boot-accessibility-guard
Open

Fix Direct Boot accessibility startup#2153
smh786 wants to merge 3 commits into
keymapperorg:developfrom
smh786:codex/direct-boot-accessibility-guard

Conversation

@smh786
Copy link
Copy Markdown

@smh786 smh786 commented Jun 5, 2026

Summary

Fix Direct Boot startup so KeyMapper does not initialize credential-encrypted database-backed components before the user has unlocked the device.

The root cause found during Q25 testing was that LOCKED_BOOT_COMPLETED started the app process and then called BaseKeyMapperApp.onBootUnlocked(), which initialized normal app components while user 0 was still RUNNING_LOCKED. That path could open /data/user/0/.../databases/key_map_database before credential-encrypted storage was available, causing repeated SQLiteCantOpenDatabaseException crashes.

This PR now:

  • avoids app-wide Direct Boot awareness and marks the accessibility service as not Direct Boot aware
  • keeps app/service Hilt dependencies lazy enough that a Direct Boot process start does not eagerly construct CE/database-backed objects
  • delays accessibility controller creation until UserManager.isUserUnlocked
  • stops calling onBootUnlocked() from LOCKED_BOOT_COMPLETED
  • calls onBootUnlocked() from normal BOOT_COMPLETED, which is delivered after unlock

Reproduction

Tested on a Zinwa Q25 running BenOS Uma.1.

Installed KeyMapper 4.2.0-foss over the ROM-provided 3.2.1-foss system app, with KeyMapper Accessibility enabled and no external workaround app installed.

After reboot, before first unlock:

User 0: RUNNING_LOCKED
enabled_accessibility_services includes:
io.github.sds100.keymapper/io.github.sds100.keymapper.system.accessibility.MyAccessibilityService

Logcat shows KeyMapper trying to open CE storage before unlock:

Failed to ensure /data/user/0/io.github.sds100.keymapper/databases: mkdir failed: errno 126 (Required key not available)
SQLiteCantOpenDatabaseException: Cannot open database '/data/user/0/io.github.sds100.keymapper/databases/key_map_database'
Directory /data/user/0/io.github.sds100.keymapper/databases doesn't exist

On this device, the repeated Direct Boot crash/restart state appears to corrupt lockscreen physical-keyboard handling until the first unlock. Examples observed before first unlock:

  • Harpocrat Keyboard typed letters as uppercase.
  • Gboard/other keyboards duplicated characters.
  • adb shell getevent -lt showed only one hardware key down/up event, so duplication occurred above the Linux input layer.

Device verification

Built and tested locally on the same Q25 using a debug build installed as io.github.sds100.keymapper.debug.

Before first unlock, after this fix:

  • Android logs that the KeyMapper accessibility service is ignored as non-encryption-aware
  • KeyMapper process may still start for the Direct Boot receiver
  • BaseKeyMapperApp logs Delay init because locked
  • no KeyMapper key_map_database open attempt or SQLite fatal occurs before unlock

After first unlock:

  • KeyMapper logs onBootUnlocked then Init
  • accessibility service remains enabled
  • no crashed accessibility service is recorded

Why

This keeps KeyMapper available after the first unlock while preventing the broken Direct Boot/locked-user startup window from touching credential-encrypted app storage.

@smh786 smh786 changed the title Delay accessibility service init until user unlock Fix Direct Boot accessibility startup Jun 6, 2026
@smh786
Copy link
Copy Markdown
Author

smh786 commented Jun 6, 2026

Update: I was able to build and test this on the affected Zinwa Q25.

The original service-only guard was not enough. The confirmed root cause was LOCKED_BOOT_COMPLETED calling onBootUnlocked() while user 0 was still RUNNING_LOCKED, which initialized CE/database-backed components before credential-encrypted storage was available.

With the latest branch:

  • before first unlock: no KeyMapper key_map_database SQLite crash
  • Android ignores the accessibility service as non-encryption-aware while locked
  • KeyMapper logs Delay init because locked
  • after first unlock: KeyMapper logs onBootUnlocked then Init
  • accessibility remains enabled and is not marked crashed

This was tested without the external Q25 boot-fix workaround app installed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant